home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Mail / pine3.92 / pico / random.c < prev    next >
C/C++ Source or Header  |  1996-03-14  |  9KB  |  385 lines

  1. #if    !defined(lint) && !defined(DOS)
  2. static char rcsid[] = "$Id: random.c,v 4.15 1996/03/15 07:41:11 hubert Exp $";
  3. #endif
  4. /*
  5.  * Program:    Random routines
  6.  *
  7.  *
  8.  * Michael Seibel
  9.  * Networks and Distributed Computing
  10.  * Computing and Communications
  11.  * University of Washington
  12.  * Administration Builiding, AG-44
  13.  * Seattle, Washington, 98195, USA
  14.  * Internet: mikes@cac.washington.edu
  15.  *
  16.  * Please address all bugs and comments to "pine-bugs@cac.washington.edu"
  17.  *
  18.  *
  19.  * Pine and Pico are registered trademarks of the University of Washington.
  20.  * No commercial use of these trademarks may be made without prior written
  21.  * permission of the University of Washington.
  22.  * 
  23.  * Pine, Pico, and Pilot software and its included text are Copyright
  24.  * 1989-1996 by the University of Washington.
  25.  * 
  26.  * The full text of our legal notices is contained in the file called
  27.  * CPYRIGHT, included with this distribution.
  28.  *
  29.  */
  30. /*
  31.  * This file contains the command processing functions for a number of random
  32.  * commands. There is no functional grouping here, for sure.
  33.  */
  34.  
  35. #include        <stdio.h>
  36. #include    "osdep.h"
  37. #include    "pico.h"
  38. #include    "estruct.h"
  39. #include        "edef.h"
  40.  
  41. #ifdef    ANSI
  42.     int getccol(int);
  43. #else
  44.     int getccol();
  45. #endif
  46.  
  47. int     tabsize;                        /* Tab size (0: use real tabs)  */
  48.  
  49.  
  50. /*
  51.  * Display the current position of the cursor, in origin 1 X-Y coordinates,
  52.  * the character that is under the cursor (in octal), and the fraction of the
  53.  * text that is before the cursor. The displayed column is not the current
  54.  * column, but the column that would be used on an infinite width display.
  55.  * Normally this is bound to "C-X =".
  56.  */
  57. showcpos(f, n)
  58. int f, n;
  59. {
  60.     register LINE   *clp;
  61.     register long   nch;
  62.     register int    cbo;
  63.     register long   nbc;
  64.     register int    lines;
  65.     register int    thisline;
  66.     char     buffer[80];
  67.  
  68.     clp = lforw(curbp->b_linep);            /* Grovel the data.     */
  69.     cbo = 0;
  70.     nch = 0L;
  71.     lines = 0;
  72.     for (;;) {
  73.     if (clp==curwp->w_dotp && cbo==curwp->w_doto) {
  74.         thisline = lines;
  75.         nbc = nch;
  76.     }
  77.     if (cbo == llength(clp)) {
  78.         if (clp == curbp->b_linep)
  79.           break;
  80.         clp = lforw(clp);
  81.         cbo = 0;
  82.         lines++;
  83.     } else
  84.       ++cbo;
  85.     ++nch;
  86.     }
  87.  
  88.     sprintf(buffer,"line %d of %d (%d%%%%), character %ld of %ld (%d%%%%)",
  89.         thisline+1, lines+1, (int)((100L*(thisline+1))/(lines+1)),
  90.         nbc, nch, (nch) ? (int)((100L*nbc)/nch) : 0);
  91.  
  92.     emlwrite(buffer, NULL);
  93.     return (TRUE);
  94. }
  95.  
  96.  
  97. /*
  98.  * Return current column.  Stop at first non-blank given TRUE argument.
  99.  */
  100. getccol(bflg)
  101. int bflg;
  102. {
  103.     register int c, i, col;
  104.  
  105.     col = 0;
  106.     for (i=0; i<curwp->w_doto; ++i) {
  107.     c = lgetc(curwp->w_dotp, i).c;
  108.     if (c!=' ' && c!='\t' && bflg)
  109.       break;
  110.  
  111.     if (c == '\t')
  112.       col |= 0x07;
  113.     else if (c<0x20 || c==0x7F)
  114.       ++col;
  115.  
  116.     ++col;
  117.     }
  118.  
  119.     return(col);
  120. }
  121.  
  122.  
  123.  
  124. /*
  125.  * Set tab size if given non-default argument (n <> 1).  Otherwise, insert a
  126.  * tab into file.  If given argument, n, of zero, change to true tabs.
  127.  * If n > 1, simulate tab stop every n-characters using spaces. This has to be
  128.  * done in this slightly funny way because the tab (in ASCII) has been turned
  129.  * into "C-I" (in 10 bit code) already. Bound to "C-I".
  130.  */
  131. tab(f, n)
  132. {
  133.     if (n < 0)
  134.       return (FALSE);
  135.  
  136.     if (n == 0 || n > 1) {
  137.     tabsize = n;
  138.     return(TRUE);
  139.     }
  140.  
  141.     if (! tabsize)
  142.       return(linsert(1, '\t'));
  143.  
  144.     return(linsert(tabsize - (getccol(FALSE) % tabsize), ' '));
  145. }
  146.  
  147.  
  148. /*
  149.  * Insert a newline. Bound to "C-M".
  150.  */
  151. newline(f, n)
  152. {
  153.     register int    s;
  154.  
  155.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  156.       return(rdonly());    /* we are in read only mode    */
  157.  
  158.     if (n < 0)
  159.       return (FALSE);
  160.  
  161.     if(optimize && (curwp->w_dotp != curwp->w_bufp->b_linep)){
  162.     int l;
  163.  
  164.     if(worthit(&l)){
  165.         if(curwp->w_doto != 0)
  166.           l++;
  167.         scrolldown(curwp, l, n);
  168.     }
  169.     }
  170.  
  171.     /* if we are in C mode and this is a default <NL> */
  172.     /* pico's never in C mode */
  173.  
  174.     /* insert some lines */
  175.     while (n--) {
  176.     if ((s=lnewline()) != TRUE)
  177.       return (s);
  178.     }
  179.     return (TRUE);
  180. }
  181.  
  182.  
  183.  
  184. /*
  185.  * Delete forward. This is real easy, because the basic delete routine does
  186.  * all of the work. Watches for negative arguments, and does the right thing.
  187.  * If any argument is present, it kills rather than deletes, to prevent loss
  188.  * of text if typed with a big argument. Normally bound to "C-D".
  189.  */
  190. forwdel(f, n)
  191. {
  192.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  193.       return(rdonly());    /* we are in read only mode    */
  194.  
  195.     if (n < 0)
  196.       return (backdel(f, -n));
  197.  
  198.     if(optimize && (curwp->w_dotp != curwp->w_bufp->b_linep)){
  199.     int l;
  200.  
  201.     if(worthit(&l) && curwp->w_doto == llength(curwp->w_dotp))
  202.       scrollup(curwp, l+1, 1);
  203.     }
  204.  
  205.     if (f != FALSE) {                       /* Really a kill.       */
  206.     if ((lastflag&CFKILL) == 0)
  207.       kdelete();
  208.     thisflag |= CFKILL;
  209.     }
  210.  
  211.     return (ldelete((long) n, f));
  212. }
  213.  
  214.  
  215.  
  216. /*
  217.  * Delete backwards. This is quite easy too, because it's all done with other
  218.  * functions. Just move the cursor back, and delete forwards. Like delete
  219.  * forward, this actually does a kill if presented with an argument. Bound to
  220.  * both "RUBOUT" and "C-H".
  221.  */
  222. backdel(f, n)
  223. {
  224.     register int    s;
  225.  
  226.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  227.       return(rdonly());    /* we are in read only mode    */
  228.  
  229.     if (n < 0)
  230.       return (forwdel(f, -n));
  231.  
  232.     if(optimize && curwp->w_dotp != curwp->w_bufp->b_linep){
  233.     int l;
  234.     
  235.     if(worthit(&l) && curwp->w_doto == 0 &&
  236.        lback(curwp->w_dotp) != curwp->w_bufp->b_linep){
  237.         if(l == curwp->w_toprow)
  238.           scrollup(curwp, l+1, 1);
  239.         else if(llength(lback(curwp->w_dotp)) == 0)
  240.           scrollup(curwp, l-1, 1);
  241.         else
  242.           scrollup(curwp, l, 1);
  243.     }
  244.     }
  245.  
  246.     if (f != FALSE) {                       /* Really a kill.       */
  247.     if ((lastflag&CFKILL) == 0)
  248.       kdelete();
  249.  
  250.     thisflag |= CFKILL;
  251.     }
  252.  
  253.     if ((s=backchar(f, n)) == TRUE)
  254.       s = ldelete((long) n, f);
  255.  
  256.     return (s);
  257. }
  258.  
  259.  
  260.  
  261. /*
  262.  * killtext - delete the line that the cursor is currently in.
  263.  *          a greatly pared down version of its former self.
  264.  */
  265. killtext(f, n)
  266. int f, n;
  267. {
  268.     register int chunk;
  269.     int         opt_scroll = 0;
  270.  
  271.     if (curbp->b_mode&MDVIEW)        /* don't allow this command if  */
  272.       return(rdonly());            /* we are in read only mode     */
  273.  
  274.     if ((lastflag&CFKILL) == 0)        /* Clear kill buffer if */
  275.       kdelete();            /* last wasn't a kill.  */
  276.  
  277.     if(gmode & MDDTKILL){        /*  */
  278.     if((chunk = llength(curwp->w_dotp) - curwp->w_doto) == 0){
  279.         chunk = 1;
  280.         if(optimize)
  281.           opt_scroll = 1;
  282.     }
  283.     }
  284.     else{
  285.     gotobol(FALSE, 1);        /* wack from bol past newline */
  286.     chunk = llength(curwp->w_dotp) + 1;
  287.     if(optimize)
  288.       opt_scroll = 1;
  289.     }
  290.  
  291.     /* optimize what motion we can */
  292.     if(opt_scroll && (curwp->w_dotp != curwp->w_bufp->b_linep)){
  293.     int l;
  294.  
  295.     if(worthit(&l))
  296.       scrollup(curwp, l, 1);
  297.     }
  298.  
  299.     thisflag |= CFKILL;
  300.     return(ldelete((long) chunk, TRUE));
  301. }
  302.  
  303.  
  304. /*
  305.  * Yank text back from the kill buffer. This is really easy. All of the work
  306.  * is done by the standard insert routines. All you do is run the loop, and
  307.  * check for errors. Bound to "C-Y".
  308.  */
  309. yank(f, n)
  310. int f, n;
  311. {
  312.     register int    c;
  313.     register int    i;
  314.  
  315.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  316.       return(rdonly());    /* we are in read only mode    */
  317.  
  318.     if (n < 0)
  319.       return (FALSE);
  320.  
  321.     if(optimize && (curwp->w_dotp != curwp->w_bufp->b_linep)){
  322.     int l;
  323.  
  324.     if(worthit(&l) && !(lastflag&CFFILL)){
  325.         register int  t = 0; 
  326.         register int  i = 0;
  327.         register int  ch;
  328.  
  329.         while((ch=fremove(i++)) >= 0)
  330.           if(ch == '\n')
  331.         t++;
  332.         if(t+l < curwp->w_toprow+curwp->w_ntrows)
  333.           scrolldown(curwp, l, t);
  334.     }
  335.     }
  336.  
  337.     if(lastflag&CFFILL){        /* if last command was fillpara() */
  338.     backchar(FALSE, 1);
  339.     gotobop(FALSE, 1);        /* then go to the top of the para */
  340.     }                    /* then splat out the saved buffer */
  341.  
  342.     while (n--) {
  343.     i = 0;
  344.     while ((c = ((lastflag&CFFILL) ? fremove(i) : kremove(i))) >= 0) {
  345.         if (c == '\n') {
  346.         if (lnewline(FALSE, 1) == FALSE)
  347.           return (FALSE);
  348.         } else {
  349.         if (linsert(1, c) == FALSE)
  350.           return (FALSE);
  351.         }
  352.  
  353.         ++i;
  354.     }
  355.     }
  356.  
  357.     if(lastflag&CFFILL){            /* if last command was fillpara() */
  358.     register LINE *botline;     /* blast the filled paragraph */
  359.     register LINE *topline;
  360.     register int  done = 0;
  361.     
  362.     fdelete();
  363.     topline = curwp->w_dotp;
  364.     gotoeop(FALSE, 1);
  365.     botline = lforw(curwp->w_dotp);
  366.     curwp->w_dotp = topline;
  367.     if(topline != botline){
  368.         while(!done){
  369.         if(lforw(curwp->w_dotp) == botline)
  370.           done++;
  371.         curwp->w_doto = 0;
  372.         ldelete((long) (llength(curwp->w_dotp) + 1), FALSE);
  373.         }
  374.     }
  375.     curwp->w_flag |= WFMODE;
  376.     
  377.     if(Pmaster == NULL){
  378.         sgarbk = TRUE;
  379.         emlwrite("");
  380.     }
  381.     }
  382.  
  383.     return (TRUE);
  384. }
  385.